package pers.cz.transform;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.LoaderClassPath;
import pers.cz.config.JefConfiguration;
import pers.cz.config.LogClientAgentConfigItem;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;

/**
 * @program: JefLogTail
 * @description: 实时日志转发
 * @author: Cheng Zhi
 * @create: 2023-03-13 20:18
 **/
public class LogForwardTransformer implements ClassFileTransformer {

    public final String[] METHOD_NAMES = new String[] {"info","debug","error","trace","warn"};

    @Override
    public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        String finalClassName = className.replace("/", ".");
        String targetClassName = JefConfiguration.get(LogClientAgentConfigItem.LOG_IMPL);
        if (finalClassName.equals(targetClassName)) {
            // 动态修改代码
            try {
                ClassPool classPool = new ClassPool(true);
                classPool.insertClassPath(new LoaderClassPath(loader));
                // 获取目标类
                CtClass ctClass = classPool.get(targetClassName);
                for (int i=0; i< METHOD_NAMES.length; i++) {
                    // 获取要监听的方法
                    CtMethod beginMethod = ctClass.getDeclaredMethod(METHOD_NAMES[i]);

                    String src = "{System.out.println($1);pers.cz.client.MessageClient.sendMessage($1);}";
                    beginMethod.insertAfter(src);
                }
                // 加载到jvm
                return ctClass.toBytecode();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
